/**
* Multiple files upload control.
* (C) Live-5 Team. All rights reserved.
*/
import flash.net.FileReferenceList;
import flash.net.FileReference;
import mx.utils.Delegate;
import com.live5.controls.PBar;
import com.live5.controls.ZButton;

class com.live5.controls.UploadControl {
	
	// UI components
	var fileInfo:TextField;
	var fileCountInfo:TextField;
	var browseBtn:MovieClip;
	var uploadBtn:MovieClip;
	var upArrowBtn:MovieClip;
	var downArrowBtn:MovieClip;
	var FileSizeInfo:TextField;
	var UploadingInfo:MovieClip;
	var TotalPBar:PBar;
	var alertWindow:MovieClip;
	//
	var fileRefList:FileReferenceList;
	var fileRefListener:Object;
	var totalBytes:Number;
	var totalUploadedBytes:Number=0;
	var singleFileUploadedBytes:Array;
	var currentFile:FileReference;
	var currentFileIndex:Number;
	var uploading:Boolean=false;
	var browsing:Boolean=true;
	var status:String;
	
	//var completedFiles:Array;
	
	// Temp vars.
	var uploadPage:String="Upload.ashx";

	/**
	* Constructor.
	*/
	function UploadControl() {
		
		fileRefListener = new Object();
		fileRefList = new FileReferenceList();
		
		// Initializing.
		status="Browsing";
		alertWindow._visible=false;
		UploadingInfo._visible=false;
		UploadingInfo.UploadingText.text="Uploading...";
		uploadBtn.Label.text = "Upload";
		browseBtn.Label.text = "Browse";
		fileInfo.background = true;
		fileInfo.backgroundColor = 0x66ff66;
		uploadBtn.enabled = false;
		
		// Bind Button events.
		browseBtn.onPress = Delegate.create(this, Browse);
		uploadBtn.onPress = Delegate.create(this, Upload);
		upArrowBtn.onPress = Delegate.create(this, UpFile);
		downArrowBtn.onPress = Delegate.create(this, DownFile);
		// Bind FileReferenceList events.
		fileRefListener.onCancel = Delegate.create(this, OnCancelHandler);
		fileRefListener.onSelect = Delegate.create(this, OnSelectHandler);
		fileRefListener.onProgress =Delegate.create(this, OnProgressHandler);
		fileRefListener.onComplete = Delegate.create(this, OnCompleteHandler);
		fileRefListener.onOpen = Delegate.create(this, OnOpenHandler);
		fileRefListener.onHTTPError =Delegate.create(this,OnHTTPErrorHandler);
		fileRefList.addListener(fileRefListener);
		this.RefreshUI();
	}
	
	/**
	* Browse button onPress handler.
	*/
	function Browse() {
		fileRefList.browse();
	}
	/**
	* Upload button onPress handler.
	*/
	function Upload(){
		var list:Array = fileRefList.fileList;
		var fileRef:FileReference;
		
		// the upload button also acts as the cancel upload button.
		if(uploadBtn.Label.text == "Upload")
		{
			this.status="Uploading";
			this.totalUploadedBytes=0;	

			// loop through the list of FileReferences and add the event handler to them, and then 
			// call the upload function
			for(var i:Number = 0; i < list.length; i++) {
				fileRef = list[i];
				
				fileRef.addListener(fileRefListener)
				if(this.singleFileUploadedBytes==null)
				{
					this.singleFileUploadedBytes=new Array();
				}
				
				singleFileUploadedBytes[fileRef.name]=0;

				//upload the file to the httphandler on the server
				// uploadPage is set in the asp.net page, it is a LoadVars variable.
				// if it isn't set, it won't upload.  This allows you to vary the page you upload to,
				// as well as pass in any query string arguments needed for the upload.
				// you can also tack on a custom file name here if you wanted.
				// depending on the uploadPage value just do something like uploadPage + "?Filename=" + customFilename
				// then you handle the file name on the server side.
				if(uploadPage != undefined){
					fileRef.upload(uploadPage);
				}
				this.RefreshUI();
			}
		}
		else
		{		
			//status_txt.text += "Upload Canceled." + '\n';
			//status_txt.vPosition = status_txt.maxVPosition;
			for(var i:Number = 0; i < list.length; i++) {
				fileRef = list[i];
				fileRef.cancel();
			}
			uploadBtn.Label.text = "Upload";
			browseBtn.enabled = true;
			this.TotalPBar.Reset();
		}
	}
	
	/**
	* Roll up current file.
	*/
	function UpFile() {
		if (currentFileIndex<(fileRefList.fileList.length-1)) {
			currentFileIndex++;
			this.RefreshUI();
		}
	}
	
	/**
	* Roll down current file.
	*/
	function DownFile() {
		if (currentFileIndex>0) {
			currentFileIndex--;
			this.RefreshUI();
		}
	}
	
	/**
	* Refresh UI.
	*/
	private function RefreshUI() {
		
		if(status=="Browsing"){
			uploadBtn.Label.text="Upload";
			uploadBtn.enabled=false;
			UploadingInfo._visible=false;
		}
		if(status=="PreUploading"){
			this.TotalPBar.Reset();
			uploadBtn.enabled = true;
		}
		if(status=="Uploading"){
	
			uploadBtn.Label.text="Cancel";
			UploadingInfo._visible=true;
			UploadingInfo.UploadingPText.text= Math.ceil(totalUploadedBytes/this.totalBytes*100).toString() + "%";
			UploadingInfo.UploadingSizeText.text = this.GetSizeType(totalUploadedBytes) +"/"+this.GetSizeType(totalBytes);
			
			return;
		}
		if(status=="Uploaded"){
			status="Browsing";
			RefreshUI();
		}
		if(fileRefList.fileList[currentFileIndex]!=null){
			currentFile =fileRefList.fileList[currentFileIndex];
			fileInfo.text = currentFile.name;
		    fileCountInfo.text ="("+ (currentFileIndex+1).toString()+"/"+fileRefList.fileList.length.toString()+")";
		    FileSizeInfo.text = this.GetSizeType(currentFile.size)+"/"+this.GetSizeType(totalBytes);
		}
	}
	
	/**
	* FileReferenceList onHTTPError handler.
	* @param	fileRef
	* @param	httpError
	*/
	function OnHTTPErrorHandler(fileRef:FileReference,httpError:Number){
		var errorInfo="http error:";
		switch(httpError){
			case 500:
			errorInfo+="Internal Server Error.";
			break;
			case 404:
			errorInfo+="Upload handler not found.";
			break;
			default:
			errorInfo+=httpError.toString();
			break;
		}
		alertWindow.ErrorInfo.text=errorInfo;
		alertWindow._visible=true;
	trace(fileRef.name);
	trace(httpError);
	}
	/**
	* FileReferenceList onCancel handler.
	*/
	function OnCancelHandler() {
		// Nothing here.
	}
	
	/**
	* FileReferenceList onOpen handler.
	*/
	function OnOpenHandler(fileRef:FileReference):Void {
		// Nothing here.
	}
	
	/**
	* FileReferenceList onSelect handler.
	*/
	function OnSelectHandler() {
		
		if (fileRefList.fileList.length>0) {
			currentFileIndex = 0;
			currentFile = fileRefList.fileList[currentFileIndex];
		} else {
			return;
		}
		fileRefList.fileList[0].onHTTPError=Delegate.create(this,OnHTTPErrorHandler);
		// set totalbytes to 0 and then add the file sizes up
		totalBytes = 0;
		
		// loop through FileReferenceList and update totalbytes.
		for (var i:Number = 0; i<fileRefList.fileList.length; i++) {
			totalBytes += fileRefList.fileList[i].size;
		}
		
		this.status="PreUploading";
		this.RefreshUI();
	}
	
	/**
	* FileReferenceList onProgress handler.
	* @param	fileRef
	* @param	bytesLoaded
	* @param	bytesTotal
	*/
	function OnProgressHandler(fileRef:FileReference, bytesLoaded:Number, bytesTotal:Number){

		var temp = bytesLoaded- singleFileUploadedBytes[fileRef.name];
	    singleFileUploadedBytes[fileRef.name]=bytesLoaded;
		
		//trace(fileRef.name+" uploaded:"+singleFileUploadedBytes[fileRef.name]);
		this.totalUploadedBytes+=temp;
		
		//trace("total uploaded:"+totalUploadedBytes);
		TotalPBar.SetProgress(totalUploadedBytes, totalBytes);
		
		this.RefreshUI();
	}
	
	/**
	* FileReferenceList onComplete handler.
	* @param	fileRef
	*/
	function OnCompleteHandler(fileRef:FileReference):Void {
		
		// All files uploaded.
		if(this.totalUploadedBytes==this.totalBytes){
			trace("upload finished");
			this.status="Uploaded";
			this.RefreshUI();
		}
	}
	
	// Converts bytes into more redable values. Called from onProgress.
	private function GetSizeType(size:Number):String {
		
		if (size<1024) {
			return int(size*100)/100+"Bytes";
		}
		if (size<1048576) {
			return int((size/1024)*100)/100+"KB";
		}
		if (size<1073741824) {
			return int((size/1048576)*100)/100+"MB";
		}
		return int((size/1073741824)*100)/100+"GB";
	}
}
